package com.kjlink.internal.report4vue.jira.controller;

import com.kjlink.internal.report4vue.base.controller.BaseApiController;
import com.kjlink.internal.workreport.helper.SessionHelper;
import com.kjlink.internal.workreport.jira.model.Jira;
import com.kjlink.internal.workreport.jira.service.JiraService;
import com.kjlink.internal.workreport.jira.service.JiraSynchronousService;
import com.kjlink.internal.workreport.jira.vo.JiraSynchronousResult;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Supplier;

/**
 * 描述:
 * 基于SSE导入jira的controller
 *
 * @author Vic.xu
 * @since 2025-01-11 9:40
 */
@RestController
public class ApiJiraSseController extends BaseApiController {

    @Resource
    private JiraService jiraService;

    @Resource
    private JiraSynchronousService jiraSynchronousService;

    // 创建一个线程池用于处理异步任务
    private final ExecutorService executor = Executors.newCachedThreadPool();

    /**
     * 导入某天的jira
     */
    @GetMapping(value = "/jira-sse/importDay", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter handleSseRequest(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate day) {
        return buildEmitter(() -> jiraSynchronousService.getGongyinJiraList(day),
                () -> jiraSynchronousService.getNotGongyinJiraList(day));
    }

    /**
     * 导入某周的jira
     */

    @GetMapping(value = "/jira-sse/importWeek", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter handleSseRequest(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
                                       @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
        return buildEmitter(() -> jiraSynchronousService.getGongyinJiraList(startDate, endDate),
                () -> jiraSynchronousService.getNotGongyinJiraList(startDate, endDate));


    }

    private SseEmitter buildEmitter(Supplier<List<Jira>> gongyinJiraListSupplier, Supplier<List<Jira>> notGongyinJIraLisrtSupplier) {
        // 创建 SseEmitter，设置超时时间（30分钟）  0L 表示无限超时时间
        SseEmitter emitter = new SseEmitter(30 * 60 * 1000L);
        //把用户信息绑定到线程以及子线程
        SessionHelper.storeUser2InheritableLocal(SessionHelper.currentUser());
        // 异步处理逻辑
        try {
            executor.submit(() -> {
                try {
                    long start = System.currentTimeMillis();
                    emitter.send(LocalTime.now() + " 开始处理数据，请稍等...");
                    // Step 1: 从系统 A 获取数据并发送总数
                    List<Jira> gongyinJiraList = gongyinJiraListSupplier.get();
                    JiraSynchronousResult gongyinResult = send(emitter, "工银", gongyinJiraList);
                    // Step 3: 从系统 B 获取数据并发送总数
                    List<Jira> notGongyinJiraList = notGongyinJIraLisrtSupplier.get();
                    // Step 4: 逐条处理系统 B 的数据并发送进度
                    JiraSynchronousResult notGongyinResult = send(emitter, "非工银", notGongyinJiraList);
                    // Step 5: 所有处理完成，发送完成消息
                    long end = System.currentTimeMillis();
                    emitter.send("所有数据处理完成！用时:" + (end - start) + "ms");
                    // 发送处理概况

                    StringBuilder summary = new StringBuilder("处理概况: \n")
                            .append("总条数 = ").append((gongyinJiraList.size() + notGongyinJiraList.size()))
                            .append("(工银 ").append(gongyinJiraList.size()).append(" + 非工银 ")
                            .append(notGongyinJiraList.size()).append(")\n")
                            .append("工  银 jira: [").append(gongyinResult.toString()).append("]\n")
                            .append("非工银 jira:[").append(notGongyinResult.toString()).append("]");

                    emitter.send(summary.toString().replace("\n", "<br/>"));

                    // 发送完成信号
                    emitter.send(SseEmitter.event().name("finished").data("done at :" + LocalTime.now()));
                    emitter.complete();
                } catch (Exception e) {
                    // 发送错误消息
                    try {
                        emitter.send(LocalTime.now() + " 处理过程中发生错误: " + e.getMessage());
                        //发生错误  则终止 ，依然使用finished  ，此处不新增eventName，省的前端需要额外处理
                        emitter.send(SseEmitter.event().name("finished").data("因异常而结束连接 " + LocalTime.now()));
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }

                    emitter.completeWithError(e);
                }
            });
        } finally {
            SessionHelper.cleanUserFromInheritableLocal();
        }

        return emitter;
    }


    public JiraSynchronousResult send(SseEmitter emitter, String from, List<Jira> list) throws Exception {
        if (CollectionUtils.isEmpty(list)) {
            emitter.send("==== 根据条件从【" + from + "】jira系统没有获取到数据! ====");
            return new JiraSynchronousResult();
        }
        emitter.send("==== 根据条件从【" + from + "】 jira系统获取jira: " + list.size() + "条 ====");
        JiraSynchronousResult summary = new JiraSynchronousResult();
        for (int i = 0; i < list.size(); i++) {
            Jira jira = list.get(i);
            String s = jiraSynchronousService.synchronousJira(jira, summary).getMessage();
            String result = "-   第" + (i + 1) + "条: " + s;
            emitter.send(result);
        }
        return summary;
    }

}
